﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;


public enum SoldierState
{
    Idle, //单位不动
    Moving, //单位移动
    Preparing, //单位准备战斗
    MeleeAttacking,
    RangedAttacking,
    Dead,
    Locking, //单位被击飞时,此时单位不由SoldierVechile控制
    Charging, //单位冲锋：单位先向目标地点移动，移动的路径上如果有敌人在前方一定距离内，则对这个敌人造成冲锋伤害。超过冲锋最大时间后，冲锋会停止
    StandHolding 
}





public enum PlayerType
{
    None,AIEnemy,Player
}

public class SoldierAI : BattleComponent<SoldierAI> {
    public Ticker AITicker = new Ticker(2,true);


    //初始化引用
    public SoldierVehicle soldierVehicle;
    public SoldierAnimator soldierAnimator;
    public NearestEnemySensor kdSensor;
    public SphereSensor sphereSensor;
    public Warrior warrior;
    public LockController lockController;

    


    //持久化数据，通常由外部来控制其改变
    public Vector3 desireTarget; //士兵期望前进的方向
    public Quaternion desireRotation; //移动到位后士兵的朝向


    //即时变动数据，由Ai本身来控制
    public SoldierState currentState;

    


    //定时器，用于状态相关需要的定时器，直接放在这里便于在Inspecter中查看
    public Timer timer = new Timer(float.MaxValue);

    


    public void OnEnable()
    {
        Assign(this);

    }

    public void OnDisable()
    {
        Unassign(this);

    }

    public static void UpdateUnitAI()
    {
        foreach(var ai in ComponentDataList)
        {
            if (ai.transform == null) continue;
            ai.timer.Tick(Time.deltaTime);
            ai.UpdateTargetEnemy();
            ai.UpdateState();
        }
    }

    public static void CleanUpSoldiers()
    {
        int i = 0;
        while(i<ComponentDataList.Count)
        {
            if(ComponentDataList[i].currentState == SoldierState.Dead)
            {
                ComponentDataList[i].gameObject.SetActive(false);
            }
            i++;
        }
    }

    

    protected void UpdateState()
    {
        soldierAnimator.meshAnimator.RestartAnim();
        switch (currentState)
        {
            case SoldierState.MeleeAttacking:
                transform.rotation = Quaternion.LookRotation(warrior.target.transform.position - transform.position);
                if (timer.IsTimerFinish(warrior.meleeAttackTime))
                {
                    ToState(SoldierState.Preparing);
                    break;
                }
                if (warrior.toLock)
                {
                    ToState(SoldierState.Locking);
                    break;
                }
                break;
            case SoldierState.Locking:
                if (lockController.lockingtype== SoldierLockingtype.ToDie && timer.IsTimerFinish(warrior.deathTime))
                {
                    ToState(SoldierState.Dead);
                    break;
                }
                if(lockController.lockingtype == SoldierLockingtype.HitFly && timer.IsTimerFinish(lockController.hitFlytime))
                {
                    ToState(SoldierState.Idle);
                    break;
                }
                if (lockController.lockingtype == SoldierLockingtype.Defend && timer.IsTimerFinish(warrior.defendTime))
                {
                    ToState(SoldierState.Idle);
                    break;
                }
                if(lockController.lockingtype == SoldierLockingtype.None)
                {
                    Debug.LogError("不能没有Lock类型");
                }
                break;
            case SoldierState.Idle:
                soldierVehicle.target = transform.position;
                soldierVehicle.targetRotation = desireRotation;
                if (warrior.toLock)
                {
                    ToState(SoldierState.Locking);
                    break;
                }
                if (warrior.target != null && warrior.target.transform.position.DistanceLessThan(transform.position, warrior.preparingRange))
                {
                    ToState(SoldierState.Preparing);
                    break;
                }
                if(warrior.target!=null && warrior.ToRangeAttack)
                {
                    ToState(SoldierState.RangedAttacking);
                    break;
                }
                if (!desireTarget.EqualZeroVector() && transform.position.DistanceGreaterThan(desireTarget, warrior.closeEnoughDistance))
                {
                    ToState(SoldierState.Moving);
                    break;
                }
                if (warrior.toCharge)
                {
                    ToState(SoldierState.Charging);
                    break;
                }
                break;
            case SoldierState.Moving:
                soldierVehicle.target = desireTarget;
                if (warrior.toLock)
                {
                    ToState(SoldierState.Locking);
                    break;
                }
                if (warrior.target != null && warrior.target.transform.position.DistanceLessThan(transform.position, warrior.preparingRange))
                {
                    ToState(SoldierState.Preparing);
                    break;
                }
                if (warrior.target != null && warrior.ToRangeAttack)
                {
                    ToState(SoldierState.RangedAttacking);
                    break;
                }
                if (desireTarget.EqualZeroVector() || transform.position.DistanceLessThan(desireTarget, warrior.closeEnoughDistance))
                {
                    ToState(SoldierState.Idle);
                    break;
                }
                if(warrior.toCharge)
                {
                    ToState(SoldierState.Charging);
                    break;
                }

                break;
            case SoldierState.Preparing:
                if (warrior.target != null)
                {
                    transform.rotation = Quaternion.LookRotation(warrior.target.transform.position - transform.position);
                    if (warrior.toLock)
                    {
                        Debug.Log(lockController.lockingtype);
                        ToState(SoldierState.Locking);
                        break;
                    }

                    if (timer.IsTimerFinish(warrior.preparingTime) && warrior.TryMeleeAttack())
                    {
                        ToState(SoldierState.MeleeAttacking);
                        break;
                    }
                    if (warrior.IsTargetInPreparingRange)
                    {
                        soldierVehicle.target = warrior.GetFihgtMove();
                    }
                    else
                    {
                        ToState(SoldierState.Idle);
                        break;
                    }

                }
                else
                {
                    ToState(SoldierState.Idle);
                }
                break;
            case SoldierState.RangedAttacking:
                if (warrior.toLock)
                {
                    ToState(SoldierState.Locking);
                    break;
                }
                if (!warrior.ableRangedAttack) ToState(SoldierState.Idle);
                if (!warrior.rangedAttackShooted && timer.IsTimerFinish(warrior.rangedAttackShootTime))
                {
                    warrior.CreatProjectile();
                }
                if (timer.IsTimerFinish(warrior.rangedAttackTime))
                {
                    if(warrior.ToRangeAttack) ToState(SoldierState.RangedAttacking);
                    else ToState(SoldierState.Idle);
                }
                break;
            case SoldierState.Dead:
                break;
            case SoldierState.Charging:
                soldierVehicle.target = desireTarget;
                if (timer.IsTimerFinish(warrior.ChargingMaxTime) || 
                    transform.position.DistanceLessThan(desireTarget, warrior.closeEnoughDistance))
                {
                    ToState(SoldierState.Idle);
                }
                if(warrior.TryChargeAttack())
                {
                    ToState(SoldierState.MeleeAttacking);
                }
                break;
        }
    }

    protected void UpdateTargetEnemy()
    {
        if(currentState != SoldierState.RangedAttacking && currentState!= SoldierState.Charging && kdSensor.NearestEnemy != null)
        {
            warrior.SetBetterTarget(kdSensor.NearestEnemy);
        }
    }


    protected void ExitState(SoldierState state)
    {
        switch(state)
        {
            case SoldierState.Locking:
                lockController.lockingtype = SoldierLockingtype.None;
                lockController.Retrive();
                soldierVehicle.enabled = true;
                warrior.enabled = true;
                warrior.toLock = false;
                break;
            case SoldierState.Charging:
                warrior.toCharge = false;
                desireTarget = transform.position;
                break;
            default:
                break;
        }
    }


    protected void ToState(SoldierState state)
    {
        if(state!= currentState)
        {
            ExitState(currentState);
        }
        switch(state)
        {
            case SoldierState.Preparing:
                currentState = SoldierState.Preparing;
                timer.Reset();
                break;
            case SoldierState.MeleeAttacking:
                currentState = SoldierState.MeleeAttacking;
                timer.Reset();
                break;
            case SoldierState.Dead:
                currentState = SoldierState.Dead;
                timer.Reset();
                break;
            case SoldierState.RangedAttacking:
                currentState = SoldierState.RangedAttacking;
                warrior.rangedAttackShooted = false;
                timer.Reset();
                break;
            case SoldierState.Locking:
                currentState = SoldierState.Locking;
                if (lockController.lockingtype == SoldierLockingtype.ToDie)
                {
                    lockController.HitFly();
                    soldierVehicle.enabled = false;
                    warrior.enabled = false;
                }
                if(lockController.lockingtype == SoldierLockingtype.HitFly)
                {
                    Debug.Log(lockController.hitFlyForce);
                    lockController.HitFly();
                    soldierVehicle.enabled = false;
                    warrior.enabled = false;
                }
                if(lockController.lockingtype == SoldierLockingtype.Defend)
                {

                }
                timer.Reset();
                break;
            case SoldierState.Charging:
                currentState = SoldierState.Charging;
                timer.Reset();
                break;
            default:
                currentState = state;
                break;
        }
    }

    public bool IsFighting
    {
        get {
            return currentState == SoldierState.Preparing
              || currentState == SoldierState.MeleeAttacking
              ; }
    }







}
